package com.mj.mes.utils;/**
 * @author cRyann
 * @create 2017-04-13 14:16
 **/

import net.sf.cglib.beans.BeanGenerator;
import net.sf.cglib.beans.BeanMap;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @author cRyann
 * @create 2017-04-13 14:16
 **/
@Service
public class BaseBeanUtil implements BaseBeanDao {
    /**
     * @param source     输入需要改变的Bean
     * @param parameters 输入需要截取的Bean属性
     * @param <T>
     * @return 输出新的Bean
     */
    public <T> Object subAttributes(T source, String... parameters) {
        HashMap propertyMap = new HashMap();
        Field[] fields = source.getClass().getDeclaredFields();
        for (Field field : fields) {
            for (String arg : parameters) {
                if (field.getName().indexOf(arg) > -1) {
                    propertyMap.put(arg, field.getType());
                }
            }
        }
        Object target = generateBean(propertyMap);
        BeanMap.create(target);
        BeanCopier copier = BeanCopier.create(source.getClass(), target.getClass(), false);
        copier.copy(source, target, null);
        return target;
    }

    public <T> Object changAttributes(T source, String... parameters) {
//        HashMap propertyMap = new HashMap();
//        // 保存原来的值
//        BeanMap sourceBeanMap = BeanMap.create(generateBean(getPropertyMap(source)));
//        Field[] fields = source.getClass().getDeclaredFields();
//        for (Field field : fields) {
//            for (int i = 0; i < parameters.length; i=i+2) {
//                if (field.getName().indexOf(parameters[i]) > -1) {
//                    propertyMap.put(parameters[i + 1], field.getType());
//                }
//                propertyMap.put(field.getName(), field.getType());
//            }
//        }
//        Object target = generateBean(propertyMap);
//        BeanMap targetbeanMap = BeanMap.create(target);
//        BeanCopier copier = BeanCopier.create(source.getClass(), target.getClass(), false);
//        //创建新的Bean
//        copier.copy(source, target, null);
//        //变更
//        for (int i = 0; i < parameters.length; i=i+2) {
//            targetbeanMap.put(parameters[i+1],sourceBeanMap.get(parameters[i]));
//        }
//        return target;
        return null;
    }

    /**
     * 增加属性并赋值
     *
     * @param source
     * @param attributeName
     * @param value
     * @param <T>
     * @param <E>
     * @return
     */
    public <T, E> Object addAttributes(T source, String attributeName, E value) {
        if (value == null) {
            return source;
        }
        HashMap propertyMap = new HashMap();
        Field[] fields = source.getClass().getDeclaredFields();
        for (Field field : fields) {
            propertyMap.put(field.getName(), field.getType());
        }
        propertyMap.put(attributeName, value.getClass());
        Object target = generateBean(propertyMap);
        BeanMap targetbeanMap = BeanMap.create(target);
        BeanCopier copier = BeanCopier.create(source.getClass(), target.getClass(), false);
        copier.copy(source, target, null);
        targetbeanMap.put(attributeName, value);
        return target;
    }

    public <T, E> Object addAttributes(T source, Map<String, E> attributeMap) {
        if (attributeMap == null) {
            return source;
        }
        HashMap propertyMap = new HashMap();
        Field[] fields = source.getClass().getDeclaredFields();
        for (Field field : fields) {
            propertyMap.put(field.getName(), field.getType());
        }
        for (Object key : attributeMap.keySet()) {
            propertyMap.put(key, attributeMap.get(key).getClass());
        }
        Object target = generateBean(propertyMap);
        BeanMap targetbeanMap = BeanMap.create(target);
        BeanCopier copier = BeanCopier.create(source.getClass(), target.getClass(), false);
        copier.copy(source, target, null);
        for (Object key : attributeMap.keySet()) {
            targetbeanMap.put(key, attributeMap.get(key));
        }
        return target;
    }

    @Override
    public <T> List<String> getNameList(T bean) {
        List<String> list = new ArrayList<>();
//        HashMap propertyMap = new HashMap();
        Field[] fields = bean.getClass().getDeclaredFields();
            for (Field field : fields) {
                list.add(field.getName());
        }
        return list;
    }

    /**
     * 根据属性Map生成Class
     *
     * @param propertyMap
     * @return
     */
    private Object generateBean(Map propertyMap) {
        BeanGenerator generator = new BeanGenerator();
        Set keySet = propertyMap.keySet();
        for (Iterator i = keySet.iterator(); i.hasNext(); ) {
            String key = (String) i.next();
            generator.addProperty(key, (Class) propertyMap.get(key));
        }
        return generator.create();
    }

    /**
     * 输入类型获取属性列表
     *
     * @param source
     * @param <T>
     * @return
     */
    private <T> HashMap getPropertyMap(T source) {
        HashMap propertyMap = new HashMap();
//        Set keySet = propertyMap.keySet();
        Field[] fields = source.getClass().getDeclaredFields();
        for (Field field : fields) {
            propertyMap.put(field.getName(), field.getType());
        }
        return propertyMap;
    }

    private <T> Object copy(T source, Object target) {
        BeanCopier copier = BeanCopier.create(source.getClass(), target.getClass(), false);
        copier.copy(source, target, null);
        return target;
    }
}
